//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension CloudTrailData {
    // MARK: Enums

    // MARK: Shapes

    public struct AuditEvent: AWSEncodableShape {
        /// The content of an audit event that comes from the event, such as userIdentity,  userAgent, and eventSource.
        public let eventData: String
        /// A checksum is a base64-SHA256 algorithm that helps you verify that CloudTrail receives the event that matches  with the checksum. Calculate the checksum by running a command like the following:  printf %s $eventdata | openssl dgst -binary -sha256 | base64
        public let eventDataChecksum: String?
        /// The original event ID from the source event.
        public let id: String

        @inlinable
        public init(eventData: String, eventDataChecksum: String? = nil, id: String) {
            self.eventData = eventData
            self.eventDataChecksum = eventDataChecksum
            self.id = id
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 128)
            try self.validate(self.id, name: "id", parent: name, min: 1)
            try self.validate(self.id, name: "id", parent: name, pattern: "^[-_A-Za-z0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case eventData = "eventData"
            case eventDataChecksum = "eventDataChecksum"
            case id = "id"
        }
    }

    public struct AuditEventResultEntry: AWSDecodableShape {
        /// The event ID assigned by CloudTrail.
        public let eventID: String
        /// The original event ID from the source event.
        public let id: String

        @inlinable
        public init(eventID: String, id: String) {
            self.eventID = eventID
            self.id = id
        }

        private enum CodingKeys: String, CodingKey {
            case eventID = "eventID"
            case id = "id"
        }
    }

    public struct PutAuditEventsRequest: AWSEncodableShape {
        /// The JSON payload of events that you want to ingest. You can also point to the JSON event payload in a file.
        public let auditEvents: [AuditEvent]
        /// The ARN or ID (the ARN suffix) of a channel.
        public let channelArn: String
        /// A unique identifier that is conditionally required when the channel's resource policy includes an external  ID. This value can be any string,  such as a passphrase or account number.
        public let externalId: String?

        @inlinable
        public init(auditEvents: [AuditEvent], channelArn: String, externalId: String? = nil) {
            self.auditEvents = auditEvents
            self.channelArn = channelArn
            self.externalId = externalId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.auditEvents, forKey: .auditEvents)
            request.encodeQuery(self.channelArn, key: "channelArn")
            request.encodeQuery(self.externalId, key: "externalId")
        }

        public func validate(name: String) throws {
            try self.auditEvents.forEach {
                try $0.validate(name: "\(name).auditEvents[]")
            }
            try self.validate(self.auditEvents, name: "auditEvents", parent: name, max: 100)
            try self.validate(self.auditEvents, name: "auditEvents", parent: name, min: 1)
            try self.validate(self.channelArn, name: "channelArn", parent: name, pattern: "^arn:.*$")
            try self.validate(self.externalId, name: "externalId", parent: name, max: 1224)
            try self.validate(self.externalId, name: "externalId", parent: name, min: 2)
            try self.validate(self.externalId, name: "externalId", parent: name, pattern: "^[\\w+=,.@:\\/-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case auditEvents = "auditEvents"
        }
    }

    public struct PutAuditEventsResponse: AWSDecodableShape {
        /// Lists events in the provided event payload that could not be  ingested into CloudTrail, and includes the error code and error message  returned for events that could not be ingested.
        public let failed: [ResultErrorEntry]
        /// Lists events in the provided event payload that were successfully ingested  into CloudTrail.
        public let successful: [AuditEventResultEntry]

        @inlinable
        public init(failed: [ResultErrorEntry], successful: [AuditEventResultEntry]) {
            self.failed = failed
            self.successful = successful
        }

        private enum CodingKeys: String, CodingKey {
            case failed = "failed"
            case successful = "successful"
        }
    }

    public struct ResultErrorEntry: AWSDecodableShape {
        /// The error code for events that could not be ingested by CloudTrail. Possible error codes include: FieldTooLong, FieldNotFound,  InvalidChecksum, InvalidData, InvalidRecipient, InvalidEventSource, AccountNotSubscribed,  Throttling, and InternalFailure.
        public let errorCode: String
        /// The message that describes the error for events that could not be ingested by CloudTrail.
        public let errorMessage: String
        /// The original event ID from the source event that could not be ingested by CloudTrail.
        public let id: String

        @inlinable
        public init(errorCode: String, errorMessage: String, id: String) {
            self.errorCode = errorCode
            self.errorMessage = errorMessage
            self.id = id
        }

        private enum CodingKeys: String, CodingKey {
            case errorCode = "errorCode"
            case errorMessage = "errorMessage"
            case id = "id"
        }
    }
}

// MARK: - Errors

/// Error enum for CloudTrailData
public struct CloudTrailDataErrorType: AWSErrorType {
    enum Code: String {
        case channelInsufficientPermission = "ChannelInsufficientPermission"
        case channelNotFound = "ChannelNotFound"
        case channelUnsupportedSchema = "ChannelUnsupportedSchema"
        case duplicatedAuditEventId = "DuplicatedAuditEventId"
        case invalidChannelARN = "InvalidChannelARN"
        case unsupportedOperationException = "UnsupportedOperationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize CloudTrailData
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// The caller's account ID must be the same as the channel owner's account ID.
    public static var channelInsufficientPermission: Self { .init(.channelInsufficientPermission) }
    /// The channel could not be found.
    public static var channelNotFound: Self { .init(.channelNotFound) }
    /// The schema type of the event is not supported.
    public static var channelUnsupportedSchema: Self { .init(.channelUnsupportedSchema) }
    /// Two or more entries in the request have the same event ID.
    public static var duplicatedAuditEventId: Self { .init(.duplicatedAuditEventId) }
    /// The specified channel ARN is not a valid  channel ARN.
    public static var invalidChannelARN: Self { .init(.invalidChannelARN) }
    /// The operation requested is not supported in this region or account.
    public static var unsupportedOperationException: Self { .init(.unsupportedOperationException) }
}

extension CloudTrailDataErrorType: Equatable {
    public static func == (lhs: CloudTrailDataErrorType, rhs: CloudTrailDataErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension CloudTrailDataErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
